<?php
/**
 * @author ZhangPeng
 * @desciption 支付回调通用类
 * @date 2015/10/17
 */

namespace Apps\Common\Pay;


use Deyi\Alipay\lib\AlipayNotify;
use Vendor\WeixinPay\WeixinPay;

Trait CallbackTrait
{
    /**
     * @author ZhangPeng
     * @desciption 记录日志
     * @date 2015/10/21
     * @return Void
     */
    private function tradeLog($type, $trade_no, $msg)
    {
        $this->getDI()->get('logger')->info($type . ': ' . $msg . '  订单号:' . $trade_no . '  时间:' . date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']));
        return true;
    }

    /**
     * @author ZhangPeng
     * @desciption 支付宝回调
     * @date 2015/10/17
     * @return Bool
     * @detail 交易状态：
     * 1.WAIT_BUYER_PAY  交易创建，等待买家付款。
     * 2.TRADE_CLOSED 在指定时间段内未支付时关闭的交易；在交易完成全额退款成功时关闭的交易。
     * 3.TRADE_SUCCESS  交易成功，且可对该交易做操作，如：多级分润、退款等。
     * 4.TRADE_FINISHED  交易成功且结束，即不可再做任何操作。
     *
     * 交易成功后的流程：
     * 1.判断该笔订单是否在商户网站中已经做过处理
     * 2.如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
     * 3.如果有做过处理，不执行商户的业务程序
     *
     * 注意：
     * 一.该种交易状态只在两种情况下出现
     * 1.开通了普通即时到账，买家付款成功后。
     * 2.开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。
     */
    public function alipayGlobal()
    {
        /*如果没有收到该页面返回的 success 信息，支付宝会在24小时内按一定的时间策略重发通知*/
        $alipayNotify = new AlipayNotify([
            'partner' => $this->getDI()->get('config')->alipay->partner,
            'sign_type' => strtoupper($this->getDI()->get('config')->alipay->signtype),
            'input_charset' => strtolower($this->getDI()->get('config')->alipay->inputcharset),
            'transport' => $this->getDI()->get('config')->alipay->transport,
            'seller_id' => $this->getDI()->get('config')->alipay->sellerid
        ]);

        /*验证成功(获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表)*/
        if ($alipayNotify->verifyNotify()) {
            switch ($_POST['trade_status']) {
                case 'TRADE_SUCCESS':
                    return true;
                case 'TRADE_FINISHED':
                    return true;
                case 'WAIT_BUYER_PAY':
                    $this->tradeLog('alipay', $_POST['trade_no'], '等待付款');
                    exit;
                case 'TRADE_CLOSED':
                    $this->tradeLog('alipay', $_POST['trade_no'], '在指定时间段内未支付');
                    exit;
                default:
                    exit;
            }
        } else {
            $this->tradeLog('alipay', $_POST['trade_no'], '验签失败');
            exit;
        }
    }

    /**
     * 微信全局回调处理
     * @version APP6.3.0
     * @author lang@vip.deyi.com
     * @param $rawBody
     * @return array|bool|mixed
     */
    public function weixinGlobal($rawBody)
    {
        $appKey = $this->getDI()->get('config')->weixinpay->appkey; //财付通密钥
        $callBackData = WeixinPay::getCallbackData($rawBody, $appKey);

        //验签成功后，返回该支付应答对象
        if ($callBackData) {
            return $callBackData;
        } else {
            $this->tradeLog('weixinpay', $callBackData("transaction_id"), '验签失败');
            echo "<br/>" . "验证签名失败";
            exit;
        }
    }

    /**
     *  解密
     *
     * @param        $decrypt
     * @param string $key
     *
     * @return string
     */
    public function decrypt($decrypt, $key = 'WV2Iqcz&')
    {
        if (!ctype_xdigit($decrypt)) {
            return false;
        }
        $decrypt = hex2bin($decrypt);
        // 不需要設定 IV
        $str = mcrypt_decrypt(MCRYPT_DES, $key, base64_decode($decrypt), MCRYPT_MODE_ECB);
        // 根據 PKCS#7 RFC 5652 Cryptographic Message Syntax (CMS) 修正 Message 移除 Padding
        $pad = ord($str[strlen($str) - 1]);

        return substr($str, 0, strlen($str) - $pad);
    }
}
